#include "gtest/gtest.h"
#include "../BaseUtil/MyTest.h"
#include "PANEImp.h"
namespace PANEImp {

class PANEElementTest : public testing::Test {
protected:

	class DummyPANEElement : public PANEElement {
	public:
		DummyPANEElement(PANEDocument * doc )
		: PANEElement("DUMMY", doc)
		{}

		virtual void render( IplImage * img ) {}
	};

    virtual void SetUp() {
    	doc = new PANEDocument();
    	elem0 = new DummyPANEElement( doc );
    	elem1 = new DummyPANEElement( doc );
    	elem2 = new DummyPANEElement( doc );
    	elem3 = new DummyPANEElement( doc );
    	elem21 = new DummyPANEElement( doc );
    	elem22 = new DummyPANEElement( doc );
    	elem221 = new DummyPANEElement( doc );
    	elem222 = new DummyPANEElement( doc );
    	elem31 = new DummyPANEElement( doc );

    	doc->appendChild( elem0 );
    	elem0->appendChild( elem1 );
    	elem0->appendChild( elem2 );
    	elem0->appendChild( elem3 );
    	elem2->appendChild( elem21 );
    	elem2->appendChild( elem22 );
    	elem22->appendChild( elem221 );
    	elem22->appendChild( elem222 );
    	elem3->appendChild( elem31 );

    	elem0->setWidth( 640 );
    	elem0->setHeight( 320 );
    }
    virtual void TearDown() {
    	delete elem31;
    	delete elem222;
    	delete elem221;
    	delete elem22;
    	delete elem21;
    	delete elem3;
    	delete elem2;
    	delete elem1;
    	delete elem0;
    	delete doc;
    }

    PANEDocument * doc;
    PANEElement *elem0, *elem1, *elem2, *elem3, *elem21, *elem22, *elem221, *elem222, *elem31;

    static bool isInRect( PANEElement * elem, long x1, long y1, long x2, long y2 ) {
    	if( elem->getLeftOffset() != x1 ) return false;
    	if( elem->getTopOffset() != y1 ) return false;
    	if( elem->getRightOffset() != x2 ) return false;
    	if( elem->getBottomOffset() != y2 ) return false;
    	return true;
    }

    static string getSize( PANEElement * pane ) {
    	ostringstream oss;
    	oss << "( " << pane->getLeftOffset() << ", " << pane->getTopOffset()
			<< ", " << pane->getRightOffset() << ", " << pane->getBottomOffset() << " )";
    	return oss.str();
    }
};

TEST_F(PANEElementTest, Offsets) {
	elem2->setWidth(100);
	elem2->setHeight(50);
	elem21->setWidth(20);
	elem21->setHeight(30);
	elem3->setWidth(40);

	ASSERT_TRUE( isInRect( elem1, 0,0,0,0 ) ) << getSize(elem1);
	ASSERT_TRUE( isInRect( elem2, 0,0,100,50 ) ) << getSize(elem2);
	ASSERT_TRUE( isInRect( elem21, 0,0,20,30 ) ) << getSize(elem21);
	ASSERT_TRUE( isInRect( elem22, 20,0,20,0 ) ) << getSize(elem22);
	ASSERT_TRUE( isInRect( elem3, 100,0,140,0 ) ) << getSize(elem3);
	ASSERT_TRUE( isInRect( elem31, 100,0,100,0 ) ) << getSize(elem31);
}

TEST_F(PANEElementTest, WidthConstraint) {
	elem2->setWidth(100);
	elem21->setWidth(80);
	elem21->setHeight(10);
	elem22->setWidth(40);
	elem22->setHeight(20);

	ASSERT_TRUE( isInRect(elem21, 0, 0, 80, 10) ) << getSize(elem21);
	ASSERT_TRUE( isInRect(elem22, 0, 10, 40, 30) ) << getSize(elem21);
	ASSERT_TRUE( isInRect(elem2, 0, 0, 100, 30 ) ) << getSize(elem2);
	ASSERT_TRUE( isInRect(elem3, 100, 0, 100, 0 ) ) << getSize(elem3);
}

TEST_F(PANEElementTest, Visible) {
	ASSERT_TRUE( elem2->getVisible() );
	ASSERT_TRUE( elem21->getVisible() );
	elem2->setVisible( false );
	ASSERT_FALSE( elem2->getVisible() );
	ASSERT_FALSE( elem21->getVisible() );
}

TEST_F(PANEElementTest, Font) {
	elem1->setFontName( "Arial" );
	elem1->setFontHeight( "10px" );
	ASSERT_STREQ( "Arial", elem1->getFontName().c_str() );
	ASSERT_STREQ( "10px", elem1->getFontHeight().c_str() );
}

}
